package com.atom.test.opengl

import android.animation.ValueAnimator
import android.graphics.Color
import android.graphics.PixelFormat
import android.graphics.PointF
import android.opengl.GLES30
import android.os.Bundle
import android.util.Log
import android.view.SurfaceHolder
import android.view.SurfaceView
import androidx.appcompat.app.AppCompatActivity
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.atom.module.lib.opengles.draw.Gl2dMesh
import com.atom.module.lib.opengles.egl.EGLHelper
import com.atom.module.lib.opengles.egl.EGLWrapper
import com.atom.module.lib.opengles.shader.GlScene
import com.atom.module.lib.opengles.shader.GlSimpleProgram
import kotlin.math.roundToInt

class DrawActivity : AppCompatActivity() {

    private lateinit var surfaceView: SurfaceView
    private lateinit var wrapper: EGLWrapper
    private var flatProgram: GlSimpleProgram? = null

    private val scene = GlScene()
    private val drawable = Gl2dMesh().apply {
        this.setPoints(
            listOf(
                PointF(0F, 0F),//0
                PointF(0F, 1F),//1
                PointF(1F, 0F),//2
                PointF(0F, -1F),//3
                PointF(-1F, 0F),//4
                PointF(0.9F, 0.7F),//5
                PointF(0.7F, 0.9F),//6
                PointF(-0.9F, -0.7F),//7
                PointF(-0.7F, -0.9F),//8
                PointF(0.9F, -0.7F),//9
                PointF(0.7F, -0.9F),//10
                PointF(-0.9F, 0.7F),//11
                PointF(-0.7F, 0.9F)//12
            )
        )
    }

    private val drawAnimator = ValueAnimator.ofFloat(0F, 1F).also {
        it.repeatCount = ValueAnimator.INFINITE
        it.repeatMode = ValueAnimator.REVERSE
        it.duration = 1200
        it.interpolator = FastOutSlowInInterpolator()
        it.addUpdateListener { draw() }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        surfaceView = SurfaceView(this)
        surfaceView.setZOrderOnTop(true)
        surfaceView.holder.setFormat(PixelFormat.RGBA_8888)
        surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(holder: SurfaceHolder) {
                onSurfaceCreated(holder)
            }

            override fun surfaceChanged(
                holder: SurfaceHolder,
                format: Int,
                width: Int,
                height: Int
            ) {

            }

            override fun surfaceDestroyed(holder: SurfaceHolder) {
                onSurfaceDestroyed()
            }
        })
        setContentView(surfaceView)
        surfaceView.setOnClickListener {

        }
    }

    private fun onSurfaceCreated(holder: SurfaceHolder) {
        wrapper = EGLHelper.initDisplay()
        wrapper.createGLESWithSurface(surface = holder.surface!!)
        flatProgram = GlSimpleProgram()
        drawAnimator.start()
    }

    private fun onSurfaceDestroyed() {
        drawAnimator.cancel()
        flatProgram?.release()
        flatProgram = null
        wrapper.release()
    }

    private fun draw() {
        Log.w("SHAPES", "drawing.")
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT)

        // Draw the circle.
        flatProgram?.setColor(Color.RED)
        //circle.radius = floatValue(0.15F, 0F)
        scene.draw(flatProgram!!, drawable)
        // Publish.
        wrapper.swapBuffers()
    }

    private fun intValue(start: Int, end: Int): Int {
        return floatValue(start.toFloat(), end.toFloat()).roundToInt()
    }

    private fun floatValue(start: Float, end: Float): Float {
        return start + drawAnimator.animatedFraction * (end - start)
    }

    override fun onDestroy() {
        onSurfaceDestroyed()
        super.onDestroy()
    }

}